#include <QScreen>
#include <QGuiApplication>
#include <QFileDialog>
#ifdef Q_OS_WIN32
#include <QAxWidget>
#include <QAxObject>
#endif
#include <QMessageBox>
#include <QWindow>
#include <QDebug>

#include <QHBoxLayout>

#ifdef Q_OS_WIN32
#include <windows.h>
#endif

#include "qlsfunc.h"

QLsFunc::QLsFunc()
{
}

/* 将窗口移动到鼠标所在的显示屏，并居中显示 */
void QLsFunc::MoveWidgetToScreenWhereMouse(QWidget *w)
{
    /* 获取显示器列表 */
    QList<QScreen *> screenList = QGuiApplication::screens();
    foreach (QScreen *screen, screenList) { /* 找到鼠标所在显示器 */
        if (screen->geometry().contains(QCursor::pos())) {
            /* 居中：screen->size().width() - width()) / 2
             * 移动到鼠标所在显示器： + screen->geometry().x()
             */
            w->move((screen->availableSize().width() - w->width()) / 2 +
                        screen->geometry().x(),
                    (screen->availableSize().height() - w->height()) / 2 +
                        screen->geometry().y());
        }
    }
}

#ifdef Q_OS_WIN32
/* 通过进程标题获取窗口进程ID */
QList<HWND> QLsFunc::GetWindowHandleListByPID(QString str_title)
{
    QList<HWND> HWND_list;
    HWND h = ::GetTopWindow(0);
    while (h) {
        DWORD pid = 0;
        DWORD dwTheardId = GetWindowThreadProcessId(h, &pid);

        if (dwTheardId != 0) {
            TCHAR *name = new TCHAR[MAX_PATH];
            ::GetWindowTextW(h, name, 255);
            QString title = QString ::fromStdWString(name);
            if (title == str_title) {
                HWND_list.append(h);
            }
        }
        h = ::GetNextWindow(h, GW_HWNDNEXT);
    }
    return HWND_list;
}

/* 关闭WID的进程 */
void QLsFunc::CloseWindowHandleByWID(WId wid)
{
    if (wid) {
        DWORD dwId = 0;
        GetWindowThreadProcessId((HWND)wid, &dwId);
        HANDLE handle = OpenProcess(PROCESS_TERMINATE, 0, dwId);
        if (handle)
            TerminateProcess(handle, 0);
        CloseHandle(handle);
        wid = 0;
    }
}

/* 打开ppt并嵌入widget中 */
WId QLsFunc::OpenPptInsetWidget(QWidget *w, QString filePath /* = ""*/)
{ /* 文件路径校验，如果为空，则调用QFileDialog令用户选择想要打开的ppt */
    if (filePath.isEmpty()) {
        filePath = QFileDialog::getOpenFileName(0, "Open ppt", QString(),
                                                "*.pptx *ppt;");
        if (filePath.isEmpty())
            return 0;
    }

    /* 连接ppt控件 */
    QAxObject *ppt_dsoframer = new QAxObject(w);
    bool ppt_state = ppt_dsoframer->setControl("Powerpoint.Application");
    if (!ppt_state)
        QMessageBox::critical(w, "Error", "no office ppt！");
    /* 获取ppt信息 */
    QMap<QString, QVariant> mapProp = ppt_dsoframer->propertyBag();
    QString versionStr = mapProp.value("Version", "0").toString();
    int pptVersion = QString(versionStr.split(".").front()).toInt();

    /* 打开并放映ppt */
    ppt_dsoframer->dynamicCall("SetVisible(bool)", true); /* 设置窗口显示 */
    ppt_dsoframer->querySubObject("Presentations()")
        ->dynamicCall("Open(string)", QDir::toNativeSeparators(
                                          filePath)); /* 选择打开ppt的路径 */
    ppt_dsoframer->querySubObject("ActivePresentation")
        ->querySubObject("SlideShowSettings")
        ->dynamicCall("Run()"); /* 放映这个剪辑 */

    /* 将ppt嵌入QWidget *w */
    /* 获取文件名 */
    int index = filePath.lastIndexOf("/");
    QString filename = filePath.mid(index + 1, filePath.length());
    /* 根据ppt标题获取进程ID */
    QList<HWND> hwndList;
    if (pptVersion > 15) { /* office version > 2010：2019兼容 */
        hwndList =
            GetWindowHandleListByPID(filename + " - PowerPoint"); /* 正常打开 */
        if (hwndList.size() == 0)
            hwndList = GetWindowHandleListByPID(
                filename + " [兼容模式] - PowerPoint"); /* 兼容 打开 */
        if (hwndList.size() == 0)
            hwndList = GetWindowHandleListByPID(
                filename + " [只读] - PowerPoint"); /* 只读 打开 */
        if (hwndList.size() == 0)
            hwndList = GetWindowHandleListByPID(
                filename +
                " [只读] [兼容模式] - PowerPoint"); /* 只读 + 兼容 打开 */
    } else { /* office version <= 2010：2010兼容 */
        hwndList = GetWindowHandleListByPID(
            filename + " - Microsoft PowerPoint"); /* 正常打开 */
        if (hwndList.size() == 0)
            hwndList = GetWindowHandleListByPID(
                filename +
                " [兼容模式] - Microsoft PowerPoint"); /* 兼容 打开 */
        if (hwndList.size() == 0)
            hwndList = GetWindowHandleListByPID(
                filename + " [只读] - Microsoft PowerPoint"); /* 只读 打开 */
        if (hwndList.size() == 0)
            hwndList = GetWindowHandleListByPID(
                filename +
                " [只读] [兼容模式] - Microsoft PowerPoint"); /* 只读 + 兼容
                                                                 打开 */
    }
    if (hwndList.size() == 0) {
        ppt_dsoframer->dynamicCall("Quit()");
        return 0;
    }
    /* 实例为QWidget并嵌入w */
    QWindow *pWin = QWindow::fromWinId((WId)hwndList.at(0));
    pWin->setGeometry(0, 0, w->width(), w->height());

    QWidget *widget = QWidget::createWindowContainer(pWin);
    widget->setMouseTracking(true);
    widget->setParent(w);

    QHBoxLayout *hLayout = nullptr;

    /**
     * 如果原先有布局，则清空布局和子控件
     *
     * 由于这里无法知道上次QWindow的WId
     * 所以外部线程的关闭就放在外面进行
     * 这里只做Layout的清理
     */
    if (w->layout()) {
        QLayoutItem *item;
        while ((item = w->layout()->takeAt(0))) {
            item->widget()->setParent(nullptr);
            delete item;
        }
        hLayout = qobject_cast<QHBoxLayout *>(w->layout());
    } else
        hLayout = new QHBoxLayout;

    hLayout->setMargin(0);
    hLayout->setSpacing(0);
    hLayout->addWidget(widget);

    w->setLayout(hLayout);

    return (WId)hwndList.at(0);
}

/* 打开word并嵌入widget中 */
WId QLsFunc::OpenWordInsetWidget(QWidget *w, QString filePath /* = ""*/)
{ /* 文件路径校验，如果为空，则调用QFileDialog令用户选择想要打开的word */
    if (filePath.isEmpty()) {
        filePath = QFileDialog::getOpenFileName(0, "Open word", QString(),
                                                "*.doc *.docx;");
        if (filePath.isEmpty())
            return 0;
    }

    /* 打开word */
    QAxWidget *word = new QAxWidget("Word.Application", 0, Qt::MSWindowsOwnDC);
    /* 获取word信息 */
    QMap<QString, QVariant> mapProp = word->propertyBag();
    qDebug() << mapProp;
    QString versionStr = mapProp.value("Version", "0").toString();
    int wordVersion = QString(versionStr.split(".").front()).toInt();
    word->setProperty("Visible", true); /* 设置窗口显示 */
    QAxObject *documents =
        word->querySubObject("Documents"); /* 获取所有的工作文档 */
    documents->dynamicCall(
        "Open(QString)",
        QDir::toNativeSeparators(
            filePath)); /* 以文件template.doc为模版新建一个文档 */
    word->querySubObject("ActiveDocument"); /* 获取当前激活的文档 */

    /* 将word嵌入QWidget *w */
    /* 获取文件名 */
    int index = filePath.lastIndexOf("/");
    QString filename = filePath.mid(index + 1, filePath.length());
    /* 根据word标题获取进程ID */
    QList<HWND> hwndList;
    if (wordVersion > 15) { /* office version > 2010：2019兼容 */
        hwndList =
            GetWindowHandleListByPID(filename + " - Word"); /* 正常打开 */
        if (hwndList.size() == 0)
            hwndList = GetWindowHandleListByPID(
                filename + " [兼容模式] - Word"); /* 兼容 打开 */
        if (hwndList.size() == 0)
            hwndList = GetWindowHandleListByPID(
                filename + " [只读] - Word"); /* 只读 打开 */
        if (hwndList.size() == 0)
            hwndList = GetWindowHandleListByPID(
                filename + " [只读] [兼容模式] - Word"); /* 只读 + 兼容 打开 */
    } else { /* office version <= 2010：2010兼容 */
        hwndList = GetWindowHandleListByPID(filename +
                                            " - Microsoft Word"); /* 正常打开 */
        if (hwndList.size() == 0)
            hwndList = GetWindowHandleListByPID(
                filename + " [兼容模式] - Microsoft Word"); /* 兼容 打开 */
        if (hwndList.size() == 0)
            hwndList = GetWindowHandleListByPID(
                filename + " [只读] - Microsoft Word"); /* 只读 打开 */
        if (hwndList.size() == 0)
            hwndList = GetWindowHandleListByPID(
                filename +
                " [只读] [兼容模式] - Microsoft Word"); /* 只读 + 兼容 打开 */
    }
    if (hwndList.size() == 0) {
        word->dynamicCall("Quit()");
        return 0;
    }
    /* 实例为QWidget并嵌入w */
    QWindow *pWin = QWindow::fromWinId((WId)hwndList.at(0));
    pWin->setGeometry(0, 0, w->width(), w->height());

    QWidget *widget = QWidget::createWindowContainer(pWin);
    widget->setMouseTracking(true); //鼠标跟踪
    widget->setParent(w);

    QHBoxLayout *hLayout = nullptr;

    /**
     * 如果原先有布局，则清空布局和子控件
     *
     * 由于这里无法知道上次QWindow的WId
     * 所以外部线程的关闭就放在外面进行
     * 这里只做Layout的清理
     */
    if (w->layout()) {
        QLayoutItem *item;
        while ((item = w->layout()->takeAt(0))) {
            item->widget()->setParent(nullptr);
            delete item;
        }
        hLayout = qobject_cast<QHBoxLayout *>(w->layout());
    } else
        hLayout = new QHBoxLayout;

    hLayout->setMargin(0);
    hLayout->setSpacing(0);
    hLayout->addWidget(widget);
    w->setLayout(hLayout);

    return (WId)hwndList.at(0);
}
#endif
